/*****************************************************************************
*                     Organizaci�n de Datos - 75.06                          *
*                         C�tedra Lic. Servetto                              *
*            Facultad de Ingenier�a - Universidad de Buenos Aires            *
******************************************************************************/ 

#include <string>
#include <iostream>
#include <sstream>

#include "ArchivoEnMemoria.h"

#include "../Comun/ConversorDeStreams.h"
#include "../Comun/Sort.h"
using namespace std;
using namespace Comun;
using namespace ComunPrueba;

int main()
{   
	// Creo un grupo (Descripcion:string, Identificador:int, (Codigo:string, Descripcion:string)+)

	/*Grupo& grupo = *new Grupo();
	grupo.GrupoId = 100000;

	Atributo& descripcion = *new Atributo("Nombre_Atributo_1_De_Grupo", "Valor_Atributo_1_De_Grupo");
	descripcion.Tipo = Cadena;
	grupo.Atributos.push_back(descripcion);

	Atributo& identificador = *new Atributo("Nombre_Atributo_2_De_Grupo", "Valor_Atributo_2_De_Grupo");
	identificador.Tipo = Cadena;
	grupo.Atributos.push_back(identificador);

	Registro& mazda = *new Registro();
	mazda.Tamanio = 333333;
	
	Atributo& codigoMazda = *new Atributo("Nombre_Atributo_1_De_Registro_1", "Valor_Atributo_2_De_Registro_1");
	codigoMazda.Tipo = Cadena;
	mazda.Atributos.push_back(codigoMazda);

	Atributo& descripcionMazda = *new Atributo("Nombre_Atributo_2_De_Registro_1", "Valor_Atributo_2_De_Registro_1");
	descripcionMazda.Tipo = Cadena;
	mazda.Atributos.push_back(descripcionMazda);

	grupo.Registros.push_back(mazda);

	Registro& ford = *new Registro();
	ford.Tamanio = 666666;
	
	Atributo& codigoFord = *new Atributo("Nombre_Atributo_1_De_Registro_2", "Valor_Atributo_1_De_Registro_2");
	codigoFord.Tipo = Cadena;
	ford.Atributos.push_back(codigoFord);

	Atributo& descripcionFord = *new Atributo("Nombre_Atributo_2_De_Registro_2", "Valor_Atributo_2_De_Registro_2");
	descripcionFord.Tipo = Cadena;
	ford.Atributos.push_back(descripcionFord);

	grupo.Registros.push_back(ford);

	stringstream salida;

	ConversorDeStreams::DatosDeGrupoAStream(grupo, &salida);

	Grupo& nuevoGrupo = ConversorDeStreams::StreamADatosDeGrupo(&salida);

	cout << endl;
	cout << grupo.GrupoId << " | " << nuevoGrupo.GrupoId << endl;
	cout << endl;
	cout << endl;
	cout << (*grupo.Atributos.begin()).Nombre << " | " << (*nuevoGrupo.Atributos.begin()).Nombre << endl;
	cout << (*grupo.Atributos.begin()).Tipo << " | " << (*nuevoGrupo.Atributos.begin()).Tipo << endl;
	cout << (*grupo.Atributos.begin()).Valor << " | " << (*nuevoGrupo.Atributos.begin()).Valor << endl;
	cout << endl;
	cout << (* (--grupo.Atributos.end()) ).Nombre << " | " << (* (--nuevoGrupo.Atributos.end()) ).Nombre << endl;
	cout << (* (--grupo.Atributos.end()) ).Tipo   << " | " << (* (--nuevoGrupo.Atributos.end()) ).Tipo << endl;
	cout << (* (--grupo.Atributos.end()) ).Valor  << " | " << (* (--nuevoGrupo.Atributos.end()) ).Valor << endl;
	cout << endl;
	cout << endl;
	cout << (* grupo.Registros.begin() ).Tamanio   << " | " << (* nuevoGrupo.Registros.begin() ).Tamanio << endl;
	cout << endl;
	cout << endl;
	cout << (* (* grupo.Registros.begin() ).Atributos.begin() ).Nombre << " | " << (* (* nuevoGrupo.Registros.begin() ).Atributos.begin() ).Nombre << endl;
	cout << (* (* grupo.Registros.begin() ).Atributos.begin() ).Tipo   << " | " << (* (* nuevoGrupo.Registros.begin() ).Atributos.begin() ).Tipo   << endl;
	cout << (* (* grupo.Registros.begin() ).Atributos.begin() ).Valor  << " | " << (* (* nuevoGrupo.Registros.begin() ).Atributos.begin() ).Valor  << endl;
	cout << endl;
	cout << (* (--(* grupo.Registros.begin() ).Atributos.end()) ).Nombre << " | " << (*(--(*nuevoGrupo.Registros.begin()).Atributos.end())).Nombre << endl;
	cout << (* (--(* grupo.Registros.begin() ).Atributos.end()) ).Tipo << " | " << (*(--(*nuevoGrupo.Registros.begin()).Atributos.end())).Tipo << endl;
	cout << (* (--(* grupo.Registros.begin() ).Atributos.end()) ).Valor << " | " << (*(--(*nuevoGrupo.Registros.begin()).Atributos.end())).Valor << endl;
	cout << endl;
	cout << endl;
	cout << (*--grupo.Registros.end()).Tamanio << " | " << (*--nuevoGrupo.Registros.end()).Tamanio << endl;
	cout << endl;
	cout << endl;
	cout << (*(*--grupo.Registros.end()).Atributos.begin()).Nombre << " | " << (*(*--nuevoGrupo.Registros.end()).Atributos.begin()).Nombre << endl;
	cout << (*(*--grupo.Registros.end()).Atributos.begin()).Tipo << " | " << (*(*--nuevoGrupo.Registros.end()).Atributos.begin()).Tipo << endl;
	cout << (*(*--grupo.Registros.end()).Atributos.begin()).Valor << " | " << (*(*--nuevoGrupo.Registros.end()).Atributos.begin()).Valor << endl;
	cout << endl;
	cout << (*(--(*(--grupo.Registros.end())).Atributos.end())).Nombre << " | " << (*--(*--nuevoGrupo.Registros.end()).Atributos.end()).Nombre << endl;
	cout << (*(--(*(--grupo.Registros.end())).Atributos.end())).Tipo << " | " << (*--(*--nuevoGrupo.Registros.end()).Atributos.end()).Tipo << endl;
	cout << (*(--(*(--grupo.Registros.end())).Atributos.end())).Valor << " | " << (*--(*--nuevoGrupo.Registros.end()).Atributos.end()).Valor << endl;

	cout << endl;
	cout << endl;
	cout << endl;
	cout << endl;

	cout << grupo.GrupoId << endl;
	cout << (*grupo.Atributos.begin()).Nombre << endl;
	cout << (*grupo.Atributos.begin()).Tipo << endl;
	cout << (*grupo.Atributos.begin()).Valor << endl;
	cout << (* (--grupo.Atributos.end()) ).Nombre << endl;
	cout << (* (--grupo.Atributos.end()) ).Tipo << endl;
	cout << (* (--grupo.Atributos.end()) ).Valor << endl;
	cout << (* grupo.Registros.begin() ).Tamanio << endl;
	cout << (* (* grupo.Registros.begin() ).Atributos.begin() ).Nombre << endl;
	cout << (* (* grupo.Registros.begin() ).Atributos.begin() ).Tipo << endl;
	cout << (* (* grupo.Registros.begin() ).Atributos.begin() ).Valor << endl;
	cout << (* (--(* grupo.Registros.begin() ).Atributos.end()) ).Nombre << endl;
	cout << (* (--(* grupo.Registros.begin() ).Atributos.end()) ).Tipo << endl;
	cout << (* (--(* grupo.Registros.begin() ).Atributos.end()) ).Valor << endl;
	cout << (*--grupo.Registros.end()).Tamanio << endl;
	cout << (*(*--grupo.Registros.end()).Atributos.begin()).Nombre << endl;
	cout << (*(*--grupo.Registros.end()).Atributos.begin()).Tipo << endl;
	cout << (*(*--grupo.Registros.end()).Atributos.begin()).Valor << endl;
	cout << (*(--(*(--grupo.Registros.end())).Atributos.end())).Nombre << endl;
	cout << (*(--(*(--grupo.Registros.end())).Atributos.end())).Tipo << endl;
	cout << (*(--(*(--grupo.Registros.end())).Atributos.end())).Valor << endl;

	cout << endl;
	cout << endl;
	cout << endl;
	cout << endl;

	stringstream lala;
	ConversorDeStreams::DatosDeGrupoAStream(grupo, &lala);

	cout << lala.rdbuf();

	cout << endl;

	/*
	MetadatosArchivo &metadatosArchivo = *(new MetadatosArchivo("archivo_prueba"));

	metadatosArchivo.MetadatosGrupo = new MetadatosGrupo();
	metadatosArchivo.MetadatosGrupo->MetadatosAtributos.push_back( *(new MetadatosAtributo("atributo_de_grupo_booleano", Booleano)) );
	metadatosArchivo.MetadatosGrupo->MetadatosAtributos.push_back( *(new MetadatosAtributo("atributo_de_grupo_entero", Entero)) );
	metadatosArchivo.MetadatosGrupo->MetadatosRegistro = new MetadatosRegistro();
	metadatosArchivo.MetadatosGrupo->MetadatosRegistro->MetadatosAtributos.push_back( *(new MetadatosAtributo("atributo_de_registro_entero", Entero)) );
	metadatosArchivo.MetadatosGrupo->MetadatosRegistro->MetadatosAtributos.push_back( *(new MetadatosAtributo("atributo_de_registro_cadena", Cadena)) );

	IArchivo &archivo = *(new ArchivoEnMemoria());

	Grupo &grupo = *(new Grupo());
	grupo.Atributos.push_back( *(new Atributo("atributo_de_grupo_booleano", "true")) );
	grupo.Atributos.push_back( *(new Atributo("atributo_de_grupo_entero", "2")) );
	
	Registro &registroUno = *(new Registro());
	registroUno.Atributos.push_back( *(new Atributo("atributo_de_registro_entero", "19")) );
	registroUno.Atributos.push_back( *(new Atributo("atributo_de_registro_cadena", "primer texto")) );
	grupo.Registros.push_back( registroUno );

	Registro &registroDos = *(new Registro());
	registroDos.Atributos.push_back( *(new Atributo("atributo_de_registro_entero", "24")) );
	registroDos.Atributos.push_back( *(new Atributo("atributo_de_registro_cadena", "otro texto")) );
	grupo.Registros.push_back( registroDos );

	int grupoIdRecienGuardado = archivo.GuardarGrupo( grupo );

	Grupo grupoRecuperado = archivo.LeerGrupo( grupoIdRecienGuardado );

	for(IteradorDeAtributos i = grupoRecuperado.Atributos.begin(); i != grupoRecuperado.Atributos.end(); ++i)
	{
		Atributo atributo = *i;
		cout << "Nombre = " << atributo.Nombre << endl;
		cout << "Valor = " << atributo.Valor << endl;
		cout << "-------" << endl;
	}

	cout << endl;
	cout << "*******" << endl;
	cout << endl;

	for(IteradorDeRegistros i = grupoRecuperado.Registros.begin(); i != grupoRecuperado.Registros.end(); ++i)
	{
		Registro registro = *i;
		for(IteradorDeAtributos j = registro.Atributos.begin(); j != registro.Atributos.end(); ++j)
		{
			Atributo atributo = *j;
			cout << "Nombre = " << atributo.Nombre << endl;
			cout << "Valor = " << atributo.Valor << endl;
			cout << "-------" << endl;
		}

		cout << endl;
		cout << "=======" << endl;
		cout << endl;
	}

	char caracterTemporal;
	cin >> caracterTemporal;
    */

	Atributo* at = new Atributo("DNI","xxxx");
	at->Tipo = EnteroLargo;
	Sort* ordenar = new Sort("ResultadoOperacion1.csv", *at, false, true);
	ordenar->SortExterno("Resultado.txt");
	return 0;
}
